/*
   Copyright (c) 2019 Shanghai Xuanzi Technology Co. Ltd https://xuanzi.ltd
   XZMindMap is licensed under the Mulan PSL v1.
   You can use this software according to the terms and conditions of the Mulan PSL v1.
   You may obtain a copy of Mulan PSL v1 at:
      http://license.coscl.org.cn/MulanPSL
   THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
   PURPOSE.
   See the Mulan PSL v1 for more details.

*/

package xuanzi.openmind.scenes.base;

import xuanzi.commons.graphics.PointF;
import xuanzi.openmind.layout.Box;
import xuanzi.openmind.layout.HBox;
import xuanzi.openmind.nodes.Node;
import xuanzi.openmind.nodes.Sheet;
import xuanzi.openmind.nodes.Style;
import xuanzi.openmind.renders.DefaultNodeRender;
import xuanzi.openmind.renders.RenderBuffer;

public class BoxScene implements Scene{

	HBox box = new HBox();
	
	Node root ;
	
	float levelSpace = 5;
	
	DefaultNodeRender render = createDefaultRender();
	
	public DefaultNodeRender getRender() {
		return render;
	}
	
	
	
	protected DefaultNodeRender createDefaultRender() {
		// TODO Auto-generated method stub
		return new DefaultNodeRender();
	}
	
	PointF pictureCenter = new PointF();
	
	@Override
	public PointF getPictureCenter() {
		return pictureCenter;
	}

	public void setupNode(Node node) {
		if(root==null) {
			root = node;
			root.setScene(this); 
		}
		setupNodeBox(node,box);
		box.clear(); 
		box().layout(0,0);
		pictureCenter.x = node.getNodeBound().centerX();
		pictureCenter.y = node.getNodeBound().centerY();
		box().offsetAll(-pictureCenter.x,-pictureCenter.y); 
		onLayoutChanged(node);  
	}
	
	Sheet sheet ;
	
	@Override
	public void setupNode(Node root, Sheet sheet) {
		this.sheet = sheet;
		setupNode(root);
	}
	
	protected void onLayoutChanged(Node node) {
	 
		if(node.getNodeCount()>0) {
			for(int i=0;i<node.getNodeCount();i++) { 
				Node item = node.getNode(i);
				onLayoutChanged(item);
			}
		}
	}

	protected void setupNodeBox(Node node,Box parent) {
		if(node.renderBuffer==null||node.renderBuffer.scene!=this) 
		{
			node.renderBuffer = new RenderBuffer();
			node.renderBuffer.target = node;
			setupBuffer(node);
			Box childrenBox = setupBoxs(node,parent);
			node.renderBuffer.childBound = childrenBox;
		}  
		if(node.getNodeCount()>0) {
			int count = 0;
			for(int i=0;i<node.getNodeCount();i++) { 
				Node item = node.getNode(i);
				item.setIndex(i);
				item.setLevel(node.getLevel()+1);
				setupNodeBox(item,node.renderBuffer.childBound);
				count+=item.getChildTotal();
			}
			node.setChildTotal(count);
		}
		
	}
	
	protected float itemSpace() { 
		return 5;
	}
	
	public Box setupBoxs(Node node,Box parent) {
		return null;
	}

	//
	/**
	 * 设置样式和图形的继承和默认值
	 * @param node
	 */
	protected void setupBuffer(Node node) { 
		RenderBuffer buffer = node.renderBuffer;
		RenderBuffer parent = node.getParent()!=null?node.getParent().renderBuffer:sheet!=null?sheet.getTheme():null;
		
		buffer.scene = this;
		buffer.topic = node.getTopic();
		buffer.label = node.getLabel();
		buffer.memo = node.getMemo();  
		node.setScene(this); 
		extendsBuffer(buffer,parent);
		//node.resetSize();
		
	}
	protected void extendsBuffer(RenderBuffer buffer,RenderBuffer parent) {
		//System.out.println(sheet+" extends buffer "+buffer.target.getTopic()+" : "+parent);
		if(buffer.target.getShape()==null&&parent!=null) {
			buffer.shape = parent.shape;
		}else {
			buffer.shape = buffer.target.getShape();
		}
		if(buffer.target.getLine()==null&&parent!=null) {
			buffer.line = parent.line;
		}else
			buffer.line = buffer.target.getLine();
		
		if(buffer.target.getStyle()!=null) {
			Style.extendsStyle(buffer, buffer.target.getStyle());
		}
		Style.extendsStyle(buffer, parent);
	}

	@Override
	public Box box() {
		
		return box ;
	}
	
	protected PointF front = new PointF(),back = new PointF();

  
}
